import { createVNode, inject, render, type App, type Plugin } from "vue";
import SimpleToastVue from "./SimpleToast.vue";

export type ToastType = "success" | "error" | "info" | "warning";
export type ToastPosition =
  | "top-left"
  | "top-center"
  | "top-right"
  | "bottom-left"
  | "bottom-center"
  | "bottom-right";

export interface ToastOptions {
  message: string;
  type?: ToastType;
  duration?: number;
  position?: ToastPosition;
}

export interface SimpleToastPlugin {
  /**
   * 显示一个普通的toast消息
   * @param message 要显示的消息
   * @param options 可选的配置项
   */
  show(message: string, options?: Partial<ToastOptions>): void;

  /**
   * 显示一个成功的toast消息
   * @param message 要显示的消息
   * @param options 可选的配置项
   */
  success(message: string, options?: Omit<Partial<ToastOptions>, "type">): void;

  /**
   * 显示一个错误的toast消息
   * @param message 要显示的消息
   * @param options 可选的配置项
   */
  error(message: string, options?: Omit<Partial<ToastOptions>, "type">): void;

  /**
   * 显示一个信息toast消息
   * @param message 要显示的消息
   * @param options 可选的配置项
   */
  info(message: string, options?: Omit<Partial<ToastOptions>, "type">): void;

  /**
   * 显示一个警告toast消息
   * @param message 要显示的消息
   * @param options 可选的配置项
   */
  warning(message: string, options?: Omit<Partial<ToastOptions>, "type">): void;
}

// 为 Vue 扩展全局属性
declare module "vue" {
  export interface ComponentCustomProperties {
    $simpleToast: SimpleToastPlugin;
  }
}

export const SIMPLE_TOAST_SYMBOL = Symbol("simple-toast");

// 为每个位置创建独立的容器
const createContainer = (position: ToastPosition) => {
  const containerId = `simple-toast-container-${position}`;
  let container = document.getElementById(containerId);

  if (!container) {
    container = document.createElement("div");
    container.id = containerId;
    container.className = "fixed z-50 flex flex-col gap-2";

    // 根据位置设置样式
    switch (position) {
      case "top-left":
        container.style.cssText = "top: 1rem; left: 1rem;";
        break;
      case "top-center":
        container.style.cssText =
          "top: 1rem; left: 50%; transform: translateX(-50%);";
        break;
      case "top-right":
        container.style.cssText = "top: 1rem; right: 1rem;";
        break;
      case "bottom-left":
        container.style.cssText =
          "bottom: 1rem; left: 1rem; flex-direction: column-reverse;";
        break;
      case "bottom-center":
        container.style.cssText =
          "bottom: 1rem; left: 50%; transform: translateX(-50%); flex-direction: column-reverse;";
        break;
      case "bottom-right":
        container.style.cssText =
          "bottom: 1rem; right: 1rem; flex-direction: column-reverse;";
        break;
    }

    document.body.appendChild(container);
  }

  return container;
};

const simpleToast = {
  createToast(options: ToastOptions) {
    const position = options.position || "top-center";
    const container = createContainer(position);
    const toastContainer = document.createElement("div");

    const vnode = createVNode(SimpleToastVue, {
      ...options,
      standalone: false,
      onDestroy: () => {
        render(null, toastContainer);
        toastContainer.remove();

        // 如果容器为空，移除容器
        if (container.children.length === 0) {
          container.remove();
        }
      },
    });

    render(vnode, toastContainer);

    // 根据位置决定插入位置
    if (position.startsWith("bottom")) {
      container.appendChild(toastContainer);
    } else {
      container.insertBefore(toastContainer, container.firstChild);
    }
  },

  show(message: string, options: Partial<ToastOptions> = {}) {
    this.createToast({
      message,
      type: options.type || "info",
      duration: options.duration || 3000,
      position: options.position || "top-center",
    });
  },

  success(message: string, options: Omit<Partial<ToastOptions>, "type"> = {}) {
    this.show(message, { ...options, type: "success" });
  },

  error(message: string, options: Omit<Partial<ToastOptions>, "type"> = {}) {
    this.show(message, { ...options, type: "error" });
  },

  info(message: string, options: Omit<Partial<ToastOptions>, "type"> = {}) {
    this.show(message, { ...options, type: "info" });
  },

  warning(message: string, options: Omit<Partial<ToastOptions>, "type"> = {}) {
    this.show(message, { ...options, type: "warning" });
  },
};

export const plugin: Plugin = {
  install(app: App) {
    app.config.globalProperties.$simpleToast = simpleToast;
    app.provide(SIMPLE_TOAST_SYMBOL, simpleToast);
  },
};

export function useSimpleToast(): SimpleToastPlugin {
  return inject<SimpleToastPlugin>(SIMPLE_TOAST_SYMBOL) || simpleToast;
}

export default plugin;
